home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / September 93.iso / Archives / Utilities / Disk & File / Disk / Icons / Icon Disposer / ShowINIT.a < prev    next >
Text File  |  1993-04-14  |  21KB  |  450 lines

  1. ; File: ShowINIT.a
  2. ; Last Modified: Sunday, January 24, 1993 9:15:18 PM
  3. ;
  4. ; # after any modification, please execute the following giberish to update the dates in this file
  5. ; find ∞ "{active}"; replace \(([∂"∂'])®0Version of )®1≈\ "®1`date -d -s`®0" "{active}"
  6. ; find • "{active}"; replace /(Last∂ Modified: )®0≈/ "®0`date`" "{active}"
  7. ;————————————————————————————————————————————————————————————————————————————————————————————————
  8. ;
  9. ;  INIT notification routine
  10. ;  by Paul Mercer, Darin Adler, Paul Snively, Frédéric Miserey, Alex Rosenberg,
  11. ;  and François Grieu, from an idea by Steve Capps
  12. ;
  13. ;  The whole thing is for drawing an extension's icon during the boot process;
  14. ;  this code has had a complicated life cycle: there are dozens of different
  15. ;  versions around in the wilderness.
  16. ;
  17. ;  François Grieu, latest offender of this code, is on AppleLink  FRA0003
  18. ;  the internet address is:   FRA0003@AppleLink.Apple.COM
  19. ;
  20. ;  This particular variation :
  21. ;  - knows how to wrap around the screen, for thoose with many inits; this only
  22. ;    works with cooperating ShowINITs
  23. ;  - draw from  ICN#/icl4/icl8  combos, now the standard for icons; the best
  24. ;    source is choosen according to main screen pixel depth and available resources
  25. ;  - does NOT support the ‘old’ cicn  resources
  26. ;  - displays a nice empty square if no valid ICN# is present (new feature)
  27. ;  - has been rewritten for extreme compactness: shrinked from 964 to 500 bytes,
  28. ;    while lot of error prevention and checking was added.
  29. ;  - is heavily commented, hopefuly compensating much of the obfuscation introduced.
  30. ;  
  31. ;  as supplied, the programming interface is :
  32. ;
  33. ;    extern pascal void ShowINIT(short iconID, short moveX);
  34. ;
  35. ;    PROCEDURE ShowINIT(iconID: INTEGER, moveX: INTEGER); EXTERNAL
  36. ;
  37. ;    iconID:    resource ID of an ICN#, and (optionaly) of an icl4 and/or icl8
  38. ;    moveX:    horizontal displacement for next icon; legitimate values are
  39. ;        -1 or 40    standard 40 pixels displacement
  40. ;        0        no displacement (for animation purproses)
  41. ;
  42. ;  a typical INIT with a small animation looks like :
  43. ;
  44. ;    ShowINIT(128,0);    /* draw first icon, don't move */
  45. ;    doMyOwnjob();        /* do some usefull stuff */
  46. ;    ShowINIT(129,-1);    /* draw second icon, advance for next */
  47. ;
  48. ;
  49. ; (FRG: My first idea was to remove the moveX parameter entirely, since I never use it;
  50. ;  later I realised it meant others could not just use my code as a drop-in replacement,
  51. ;  and precluded animations; thus, I introduced an assembly option to control what moveX
  52. ;  does, and if it exists; see below under  moveX_option)
  53. ;
  54. ;————————————————————————————————————————————————————————————————————————————————————————————————
  55. ; Revision history
  56. ;
  57. ; 6/7/87     PM   - Created First version.
  58. ; 6/15/87    PM   - Changed to standard (Pascal) calling conventions.
  59. ; 6/20/87    PM   - Fixed color & Finder bug on Mac II.
  60. ; 6/22/87    DBA  - Improved handling of QuickDraw.
  61. ; 6/29/87    DBA  - Used scratch8 to avoid conflict with “Easy Access”.
  62. ; 6/30/87    DBA  - Changed to a 4-byte scheme with “checksum”.
  63. ; 6/30/87    PFS  - Separated into ShowINIT and InnerShowINIT.
  64. ; 7/1/87     DBA  - Fixed stack bug and switched to CurApName.
  65. ; 7/2/87     PM   - Added check for old signature in ApplScratch for backword compatibility
  66. ;                   (TMON Startup).
  67. ; 7/3/87     PM   - Removed _SysBeep in ErrorExit since it causes a crash.
  68. ;                 - Also changed ICN# plotter to srcOr mode for Blinker.
  69. ; 7/13/87    PM   - Fixed A3 trashing bug in InnerShowINIT - exit code left word on stack
  70. ;                   (reported by D. Dunham).
  71. ; 7/21/87    PM   - Due to popular demand, InitGraf is no longer being called.
  72. ;                   This avoids the gamma correction problem with Startupscreens getting
  73. ;                   “washed out” by ShowINIT, though someone else is still bound to call
  74. ;                   InitGraf sooner or later (i.e. InitWindows).
  75. ; 7/29/87    PM   - Put InitGraf back in; this is required (reported by C. Derossi at Apple
  76. ;                   Tech Support).
  77. ;                 - Took out GetPort/SetPort.
  78. ; 10/6/87    PM   - Set CurrentA5 properly.  Rearranged myVars.
  79. ; 12/28/87   PM   - Major revision to accomodate future INIT31 based ShowINIT.
  80. ; 7/14/88    PM   - Major revision to get rid of above 'accomodations'.
  81. ;                 - Added color icon 'cicn' support and fixed beep crash.
  82. ;                 - Removed support for old signature.
  83. ; 11/25/89   PM   - Added Y dimension support, icl4/8 support to get rid of 'obsolete' cicns.
  84. ; 3/27/90    AMR  - 'cicn's were not being drawn in their native size
  85. ; 11/30/91   FRG  - Started from source found on ‘Lord of the Files’, dev. CD Vol VII.
  86. ;                 - Removed cicn support - these are obsolete and may cause palette problems
  87. ;                 - Introduced a right margin (causes wraparound sooner on a few sreens).
  88. ;                 - Simplified A5 world allocation; all variables now A5-based
  89. ;                 - Initialized more fields in the PixMap.
  90. ;                 - Added a check that ICN#/icl4/icl8 resources are at least the expected size;
  91. ;                   blockmoved these into variables and disposed the Resource immediately;
  92. ;                   default drawing if no ICN# can be loaded; many other sanity cheks.
  93. ;                 - Rather than disposing the Color Map of the PixMap returned by _NewPixMap and
  94. ;                   later manufacturing an empty Color Map before disposing the PixMap, we now
  95. ;                   save the original Color Map, and restore it before disposing the PixMap.
  96. ; 12/3/91    FRG  - Introduced  moveX_option  for backward link-level compatibility.
  97. ;                 - Spread subroutines to use short branchs where possible.
  98. ;                 - Firmly decided to stop shrinking the code - maybe it's too late.
  99. ; 12/4/91    FRG  - Did extensive tests on many configurations and monitor stiings, including
  100. ;                      - Plus and SE under 6.0.7 and 3.2
  101. ;                      - II under System 6.0.7 and 3.2
  102. ;                      - IIcx under System 7
  103. ;                      - IIci under 6.0.7 and 7.0.1
  104. ;                      - IIfx under 7.0 and two Apple 13" monitors
  105. ;                      - IIfx under 6.0.7 and 32 bits color (RasterOps card & monitor)
  106. ;                   not a single crash; the INIT adapts well to the environment and draws using
  107. ;                   the right resource and colors; however, there are quite a few visual
  108. ;                   glitches with old INITs, when drawing past the first line. Many keep drawing
  109. ;                   on the bottom line; some will allow only two or three lines.
  110. ;                   All in all, the method implemented seems to be the ‘official’ one, and
  111. ;                   reasonably compatible with what's around.
  112. ;                 - AppleLink relase.
  113. ; 1/24/93    CJE  - Added CASE OBJ, which allows me to link with ShowINIT, instead of SHOWINIT
  114. ;
  115. ;————————————————————————————————————————————————————————————————————————————————————————————————
  116. ;
  117.         INCLUDE    'Traps.a'
  118.         INCLUDE    'QuickEqu.a'
  119.         INCLUDE    'SysEqu.a'
  120.         CASE    OBJ
  121.         
  122. ;
  123. ;————————————————————————————————————————————————————————————————————————————————————————————————
  124. ; Assembly-time option for moveX parameter treatment. Allowable values for  moveX_option are :
  125. ;    0    ; original : negative value -> 40, other taken as is
  126. ;    1    ; enforce standard : zero -> no move, others -> 40 pixels right
  127. ;    2    ; no moveX parameter - function name changed to ShowINIT_EZ
  128. ;
  129. ; if necessay, moveX_option can be set up from the command line, for example:
  130. ;  ASM  -d moveX_option=2  ShowINIT.a
  131. ;
  132. ; with moveX_option=2, the programming interface becomes :
  133. ;
  134. ;    extern pascal void ShowINIT_EZ(short iconID);
  135. ;
  136. ;    PROCEDURE ShowINIT_EZ(iconID: INTEGER); EXTERNAL
  137. ;
  138. ;
  139.     IF &TYPE('moveX_option') = 'UNDEFINED' THEN
  140. moveX_option    SET    0            ; default to old behaviour
  141.     ENDIF
  142. ;
  143. ;
  144.         PROC
  145.     IF moveX_option <> 2 THEN ; option 2 supresses the moveX parameter and change name
  146.         EXPORT    (ShowINIT):CODE        ; keep standard name
  147.     ELSE
  148.         EXPORT    (ShowINIT_EZ):CODE    ; name when no moveX parameter
  149.     ENDIF
  150. ;
  151. ; other constants
  152. iconSize    EQU    32        ; X & Y size of icons (don't even think to change this…)
  153. iconSpacer    EQU    8        ; X & Y spacing, and top/left/bottom/right sreen margin
  154. checksumConst    EQU    $1021        ; constant used for computing checksum
  155. minColorDepth    EQU    4        ; minimum bits/pixel for drawing color icons
  156. iconRowBytes    EQU    32/8        ; 32/8 bits
  157. hasCQDBit    EQU    6        ; this bit in ROM85 is cleared if Color QuickDraw is available
  158. ;
  159. ; remanent low mem variables; CurApName+32-8 is a GREAT place to store 8 bytes (it was Darin's idea)
  160. myVCheck    EQU    CurApName+32-8    ; a simple checksum of myV to determine first-timeness
  161. myV        EQU    myVCheck+2    ; current vertical position
  162. myH        EQU    myV+2        ; current horizontal position
  163. myHCheck    EQU    myH+2        ; a simple checksum of myH to determine first-timeness
  164. ;
  165. ; our register list: D7 and A6 are still for rent !!
  166. savedRegList    REG    D3-D6/A2-A5    ; registers used - adjust savedRegCnt accordingly
  167. savedRegCnt    EQU    8        ; count of saved registers
  168.  
  169. ; our variables and buffers; allocated on the stack, making an A5 world
  170. ; insert new fields only as advertised; do not reorder
  171. stackFrame    RECORD    {A5Link},DECR    ; build a stack frame record
  172. paramBegin    EQU    *        ; start parameters after this point
  173. iconID        DS.W    1        ; resource ID of the ICN#/icl4/icl8 combo
  174.     IF moveX_option <> 2 THEN ; option 2 supresses the moveX parameter
  175. moveX        DS.W    1        ; horizontal move parameter
  176.     ENDIF
  177. ; insert additionnal parameters here
  178. paramSize    EQU    paramBegin-*    ; size of all the passed parameters
  179.          DS.L    1        ; place holder for return address
  180.         DS.L    savedRegCnt    ; place holder for saved registers
  181. A5Link        DS.L    1        ; QuickDraw will stuff a pointer to his variables here
  182. ; possible location for additionnal variables
  183. thePort       DS.L    1        ; QuickDraw globals
  184.         DS.B    grafSize-4    ; other QuickDraw globals (except thePort)
  185. ; prefered location for additionnal variables
  186. myPort        DS.B    portRec        ; a private port
  187. myBitMap    DS.B    bitmapRec    ; private bitMap record for our ICN# offscreen
  188. ; possible location for additionnal variables
  189. buf_iclx    DS.B    1024        ; room for an icl8 (also hold the icl4)
  190. ; possible location for additionnal variables
  191. buf_mask    DS.B    128        ; ICN# mask
  192. buf_icon    DS.B    128        ; ICN# icon
  193. dstRect        DS.B    8        ; the rectangle we draw to - must be last
  194. varsSize    EQU    *
  195.         ENDR
  196.         WITH    stackFrame    ; cover our local stack frame
  197. ;
  198. ;————————————————————————————————————————————————————————————————————————————————————————————————
  199. ; the entry point : this is to be kept on the first instruction of the module, for compatibility
  200. ; only one of the two label is realy exported, depending on moveX_option
  201. ShowINIT:
  202. ShowINIT_EZ:
  203. ;
  204. ; first we build an A5 world on the stack. This why we save the registers before the LINK An,#
  205.         MOVEM.L    savedRegList,-(A7)            ; save registers, including A5
  206.         LINK    A5,#varsSize                ; allocate our variables & A5 world
  207.         MOVE.L    A7,A2                    ; points to dstRect - used later
  208. ;
  209. ; initialise QuickDraw gear
  210. ; we open a new port to get fresh information, and isolate the screen port from our messing
  211.         PEA    thePort(A5)
  212.         _InitGraf                    ; fixes color bug as per DA@ICOM
  213.         LEA    myPort(A5),A4                ; will later move into myBitMap
  214.         MOVE.L    A4,-(A7)                ; _ClosePort parameter (done in cleanup)
  215.         MOVE.L    A4,-(A7)                ; _OpenPort parameter
  216.         _OpenPort
  217. ;
  218. ; setup myBitMap to refer to the ICN# mask (not yet loaded)
  219.         MOVE.L    #(iconSize<<16)+iconSize,D6        ; D6 constant from now on
  220.         MOVE.L    D6,-(A4)        ;bounds.botRight
  221.         CLR.L    -(A4)            ;bounds.topLeft    ; 0-0-32-32 standard icon bounds
  222.         MOVE.W    #iconRowBytes,-(A4)    ;rowBytes
  223.         LEA    buf_mask(A5),A0                ; pointer to Mask
  224.         MOVE.L    A0,-(A4)        ;baseAddr    ; A4 is ptr to myBitMap from now on
  225. ;
  226. ; (11/30/91 FRG) build drawing coordinates and update the remanent variables
  227. ; First we calculate the rightmost position allowable.
  228. ; There is, purprosely, a small deviation from the original : we have a 7 pixels right margin.
  229. ; Also note that the moveX parameter is always ignored for wraparound calculation, as in the original,
  230. ; else it would ruin animation on the rightmost position
  231.         MOVEQ    #iconSize+iconSpacer,D2        ; (horizontal spacing) added in valid_coord
  232.         MOVE.W    myPort+portBounds+right(A5),D1    ; horizontal screen size
  233.         SUB.W    D2,D1                ; maximum in valid_coord (right margin)
  234.     IF moveX_option = 0 THEN ; original 
  235.         MOVE.W    moveX(A5),D2            ; prescribed horizontal spacing
  236.         BPL.S    more                ; must be non-negative
  237.         MOVEQ    #iconSize+iconSpacer,D2        ; default horizontal spacing
  238.     ELSEIF moveX_option = 1 THEN ; enforce regular icon spacing 
  239.         TST.W    moveX(A5)            ; flag for horizontal spacing
  240.         BNE.S    more                ; non-zero means default
  241.         MOVEQ    #0,D2                ; zero means no move
  242.     ENDIF
  243. more        MOVEQ    #0,D3                ; nothing yet to be substracted in valid_coord
  244.         MOVEQ    #iconSpacer,D4            ; default (for valid_coord)
  245.         MOVE.L    myH,D0                ; get myH & myHCheck
  246.         SWAP    D0                ; myHCheck <-> myH (reversed for historical reasons)
  247.         BSR.S    valid_coord            ; build left coordinate
  248.         SWAP    D0                ; myH <-> myHCheck (reversed for historical reasons)
  249.         MOVE.L    D0,myH                ; save updated myH & myHCheck
  250.         MOVEQ    #-(iconSize+iconSpacer),D4
  251.         ADD.W    myPort+portBounds+bottom(A5),D4    ; vertical default
  252.         MOVEQ    #0,D2                ; nothing to be added
  253.         MOVE.W    D4,D1                ; maximum (same as default)
  254.         MOVE.L    myVCheck,D0            ; get myVCheck/myV
  255.         BSR.S    valid_coord            ; build top coordinate
  256.         MOVE.L    D0,myVCheck            ; store myVCheck/myV
  257. ;
  258. ; result (topLeft of our location on the screen) is in D5. A2 points to dstRect
  259.         MOVE.L    D5,(A2)+    ;topLeft    ; save the resulting X/Y coordinate
  260.         ADD.L    D6,D5                ; compute the botRight (no overflow can occur)
  261.         MOVE.L    D5,(A2)+    ;botRight    ; make an icon-sized rect
  262. ;
  263. ; load the ICN#
  264.         MOVEQ    #256/128,D3            ; size for DATA+MASK
  265.         MOVE.L    #'ICN#',D4            ; note that here A2 points to buf_icon
  266.         BSR.S    load_rsrc            ; load the icon and mask
  267.         BEQ.S    got_mask            ; ICN# loaded ok
  268. ;
  269. ; (11/30/91 FRG) no resource loaded; draw a simple light gray rect with black border
  270.         PEA    ltGray+thePort(A5)
  271.         _BackPat                ; set background pattern to light gray
  272.         PEA    dstRect(A5)            ; _FrameRect parameter
  273.         MOVE.L    (A7),-(A7)            ; _EraseRect parameter
  274.         _EraseRect                ; make the inside
  275.         _FrameRect                ; and the border
  276.         BRA.W    cleanup
  277. ;
  278. ; (11/30/91 FRG) coordinate validator; called two times to process the H then V coordinates; trashes A0
  279. ; reg    *** on entry ***                *** on exit ***
  280. ; D0    lo:coordinate    hi:alleged checksum        lo: result coordinate    hi:updated checksum 
  281. ; D1    maximum value                    unchanged
  282. ; D2    post-offset (added for horizontal shift)    unchanged
  283. ; D3    pre-offset (substracted for vertical offset)    set to iconSize+iconSpacer if maximum exceeded
  284. ; D4    default when invalid checksum or out of bound    unchanged
  285. ; D5    lo:ignored    hi:previous result        lo: previous result    hi:result coordinate
  286. valid_coord    BSR.S    adj_chksum            ; adjust high word of D0
  287.         CMP.L    A0,D0                ; a copy of D0 was kept in A0
  288.         BEQ.S    useD0a                ; D0's checksum was OK
  289.         MOVE.W    D4,D0                ; revert to default
  290. useD0a        SUB.W    D3,D0                ; on vertical pass : move up if previous overflow
  291.         CMP.W    #iconSpacer,D0            ; check against minimum
  292.         BLO.S    useDefault            ; too left/high, use default & no line change
  293.         CMP.W    D1,D0
  294.         BLS.S    useD0b                ; check for overflow
  295.         MOVEQ    #iconSize+iconSpacer,D3        ; (vertical spacing) remember the overflow
  296. useDefault    MOVE.W    D4,D0
  297. useD0b        MOVE.W    D0,D5                ; store left / top
  298.         SWAP    D5                ; build the top point
  299.         ADD.W    D2,D0                ; add after
  300. adj_chksum    MOVE.L    D0,A0                ; fix D0's high byte
  301.         ROL.W    #1,D0
  302.         EOR.W    #checksumConst,D0
  303.         SWAP    D0
  304.         MOVE.W    A0,D0
  305.         RTS
  306. ;
  307. ; (11/30/91 FRG) load an ICN#/icl4/icl8 resource
  308. ; on entry :    A2 = destination; unchanged
  309. ;        D4 = resource type; unchanged
  310. ;        D3 = expected length/128 (either or 2,4,8). Is returned multiplied by 128
  311. ; on exit    D0 = 0 if OK, and -1 if error; flags are set accordingly
  312. load_rsrc    ASL.W    #7,D3                ; D3 *= 128
  313.         SUBQ.L    #4,A7                ; _GetResource result
  314.         MOVE.L    D4,-(A7)            ; type
  315.         MOVE.W    iconID(A5),-(A7)        ; id
  316.         _GetResource
  317.         MOVE.L    (A7)+,D0
  318.         BEQ.S    baderr                ; nil handle
  319.         MOVE.L    D0,A0
  320.         MOVE.L    (A0),D2
  321.         BEQ.S    baderr                ; purged handle
  322.         MOVE.L    A0,-(A7)            ; parameter for _ReleaseResource
  323.         _GetHandleSize
  324.         CMP.L    D3,D0
  325.         BLO.S    miderr                ; not the expected size
  326.         MOVE.L    D3,D0                ; len for _BlockMove
  327.         MOVE.L    D2,A0                ; src for _BlockMove
  328.         MOVE.L    A2,A1                ; dst for _BlockMove
  329.         _BlockMove
  330.         _ReleaseResource
  331.         MOVEQ    #0,D0                ; mark OK
  332.         RTS
  333. miderr        _ReleaseResource
  334. baderr        MOVEQ    #-1,D0                ; mark err
  335.         RTS
  336. ;
  337. ; try to draw in color; if anything fails, revert to ShowINIT1Bit 
  338. got_mask    BTST.B    #hasCQDBit,ROM85        ; does CQD exists ?
  339.         BNE.S    ShowINIT1Bit            ; no, we'll do it one bit
  340.         MOVE.L    MainDevice,D5            ; get handle to main device
  341.         BSR.S    safe_deref_D5
  342.         MOVE.L    gdPMap(A3),D5            ; get its pixmap handle
  343.         BSR.S    safe_deref_D5
  344.         MOVE.L    #'icl8',D4            ; icl8 as first choice
  345.         CMPI.W    #minColorDepth,pmPixelSize(A3)    ; test main screen depth
  346.         BLT.S    ShowINIT1Bit            ; not deep enough for us to draw in color
  347.         BEQ.S    is_4bits            ; screen is 4 bits deep, first use icl4
  348.         SUBQ.B    #4,D4                ; icl8->icl4
  349. is_4bits    LEA    buf_iclx(A5),A2            ; storage pointer for load_rsrc
  350.         MOVEQ    #1,D5                ; try to load the appropriate iclx, else try the other
  351. two_times_max    MOVEQ    #$0C,D3                ; note : high word of D3 is 0 from now on
  352.         EOR.W    D3,D4                ; alternates icl4 and icl8
  353.         AND.W    D4,D3                ; 4 or 8; after load_rsrc will become 512 or 1024
  354.         BSR.S    load_rsrc            ; load eiter the icl4 or icl8 (D3 multiplied by 128)
  355.         DBEQ    D5,two_times_max
  356.         BEQ.S    ShowINITxBit            ; found a resource, go draw in color
  357. ;
  358. ; draw the B&W ICN#
  359. ShowINIT1Bit    MOVEQ    #srcBic,D0            ; mode for Mask
  360.         BSR.S    doCopyBits
  361.         MOVEQ    #-128,D0        
  362.         ADD.L    D0,baseAddr(A4)            ; now move myBitMap to the ICON
  363.         MOVEQ    #srcOr,D0            ; mode for the ICON
  364.         BSR.S    doCopyBits
  365.         BRA.S    cleanup                ; all done
  366. ;
  367. ; (12/02/91 FRG) checks for handle just loaded in D5; if invalid, revert to ShowINIT1Bit
  368. ; returns the handle in A0, the dereferenced handle in A3 and D0; destroys A1
  369. safe_deref_D5    MOVE.L    (A7)+,A1            ; pop return address, keep flags
  370.         BEQ.S    ShowINIT1Bit            ; error - nil handle (in D5)
  371.         MOVE.L    D5,A0
  372.         MOVE.L    (A0),D0
  373.         BEQ.S    ShowINIT1Bit            ; error - purged handle
  374.         MOVE.L    D0,A3
  375.         JMP    (A1)
  376. ;
  377. ; (11/30/91 FRG) a subroutine to CopyBits myBitMap to the dstRect in said (D0) mode 
  378. doCopyBits    MOVE.L    A4,-(A7)            ; source bitmap (is myBitMap)
  379.         PEA    myPort+portBits(A5)        ; dst bitmap
  380.         PEA    myBitMap+bounds(A5)        ; srcRect
  381.         PEA    dstRect(A5)            ; dstRect
  382.         MOVE.W    D0,-(A7)            ; mode
  383.         CLR.L    -(A7)                ; no clip region
  384.         _CopyBits                ; draw it
  385.         RTS
  386.  
  387. ; draw on icl4 or icl8; we need to manufacture an offsceen pixmap
  388. ShowINITxBit    SUBQ.L    #4,A7
  389.         _NewPixMap                ; make a new PixMap
  390.         MOVE.L    (A7)+,D5            ; D5 keeps the PixMap till we dispose it
  391.         BSR.S    safe_deref_D5
  392.         _HLock                    ; lock the new PixMap
  393. ; while we point here, prepare the bitMaps/pixMaps for the _CopyMask
  394.         MOVE.L    A3,-(A7)            ; srcBits (is the new PixMap)
  395.         MOVE.L    A4,-(A7)            ; maskBits (is myBitMap)
  396.         PEA    myPort+portBits(A5)        ; dst bitmap
  397. ; now fill in the PixMap fields, in ascending order (so we save code, and won't forget anything)
  398.         MOVE.L    A2,(A3)+    ;pmBaseAddr    ; address where the icl4/icl8 was _BlockMoved
  399.         MOVE.B    #$80,(A3)+    ;pmNewFlag    ; mark as new style PixMap
  400.         LSR.W    #7-2,D3                ; depth in bit (8 or 4) multiplyed by 4
  401.         MOVE.B    D3,(A3)+    ;pmRowBytes+1    ; set Row Width in bytes (either 32 or 16)
  402. ; while we point here, prepare the Rect parameters for the _CopyMask
  403.         MOVE.L    A3,-(A7)            ; srcRect is pmBounds
  404.         MOVE.L    A3,-(A7)            ; maskRect is same
  405.         PEA    dstRect(A5)            ; dstRect
  406.         CLR.L    (A3)+        ;pmBounds.topLeft    ; set the pmBounds
  407.         MOVE.L    D6,(A3)+    ;pmBounds+botRight    ; D6 = (iconSize<<16) + iconSize
  408.         CLR.L    (A3)+        ;pmVersion/pmPackType    ; standard
  409.         CLR.L    (A3)+        ;pmPackSize        ; standard
  410.         ADDQ.L    #pmPixelType-pmHRes,A3            ; let pmHRes & pmVRes unchanged
  411.         LSR.W    #2,D3                ; depth in bit (8 or 4)
  412.         MOVE.L    D3,(A3)+    ;pmPixelType/pmPixelSize (pmPixelType zeroed=>chunky)
  413.         MOVE.W    #1,(A3)+    ;pmCmpCount    ; components in pixel, 1 for chunky
  414.         MOVE.W    D3,(A3)+    ;pmCmpSize    ; same as pmPixelSize
  415.         CLR.L    (A3)+        ;pmPlaneBytes    ; 0 for chunky
  416.         SUBQ.L    #4,A7                ; get the clut appropriate for our depth
  417.         MOVE.L    #'clut',-(A7)
  418.         MOVE.W    D3,-(A7)            ; resource id = either (8 or 4)
  419.         _RGetResource                ; hopefully can't fail on a color machine
  420.         MOVE.L    (A3),D4        ;pmTable    ; keep the original color map around
  421.         MOVE.L    (A7)+,(A3)+    ;pmTable    ; stuff the ROM clut
  422.         CLR.L    (A3)        ;pmReserved    ; ‘must be set to 0 for future compatibility’
  423. ; now do the much awaited drawing
  424.         _CopyMask                ; do the drawing
  425. ; cleanly dispose the PixMap
  426.         MOVE.L    D4,-(A3)    ;pmTable    ; restore the original color map
  427.         MOVE.L    D5,-(A7)            ; original new PixMap Handle
  428.         _DisposPixMap
  429.  
  430. ; about all done
  431. cleanup        _ClosePort                ; parameter for this one pushed long ago
  432. ; *** (DBA) I think that QuickDraw leaves handles around. Too bad we can't get rid of them…
  433.         UNLK    A5                ; de-allocate our variables - does NOT restore A5
  434.         MOVEM.L    (A7)+,savedRegList        ; restore standard registers, including A5
  435.         MOVE.L    (A7)+,A0            ; pop return address
  436.         ADDA    #paramSize,A7            ; discard parameters (optimized into ADDQ.W)
  437.         JMP    (A0)                ; all done
  438. ;————————————————————————————————————————————————————————————————————————————————————————————————
  439. ; ShowINITCredits
  440.         STRING  ASIS
  441.         DC.W    'ShowINIT by Paul Mercer'
  442.         DC.W    'Copyright 1987-1991'
  443.         DC.W    'Version of 1/24/93'
  444. ;————————————————————————————————————————————————————————————————————————————————————————————————
  445.         ENDPROC
  446.         END
  447.